﻿//
// *************************************************************************************
// WP-Framework
//
// Developed by 
// Lukas Kretschmar (lkretschmar.dev@bluewin.ch)
//
// Switzerland, Copyright (c) 2012 lkretschmar
// This content is released under the MIT License (http://opensource.org/licenses/MIT).
//     
// *************************************************************************************
//
//
			

using System;
using KretschIT.WP_Fx.Testing.I18n;

namespace KretschIT.WP_Fx.Testing
{
    public class ExceptionAssert
    {
        #region Assert

        public static void Throws<TExcepion>(Action action, Action<TExcepion> assert = null, bool allowHandlingAsBaseType = true) where TExcepion : Exception
        {
            var noExceptionOccured = false;
            AssertAction(action);
            try
            {
                action();
                noExceptionOccured = true;                
            }
            catch (TExcepion ex)
            {
                AssertExceptionType<TExcepion>(allowHandlingAsBaseType, ex);
                FurtherAsserts<TExcepion>(assert, ex);
            }
            catch (Exception ex)
            {
                ExceptionMissmatch<TExcepion>(ex);
            }
            NoExceptionOccured<TExcepion>(noExceptionOccured);
        }

        #region Assertions

        private static void AssertAction(Action action)
        {
            if (action == null)
            {
                throw new AssertInconclusiveException(Messages.Exception_NoAction);
            }
        }
        
        private static void NoExceptionOccured<TExcepion>(bool isTrue) where TExcepion : Exception
        {
            if (isTrue)
            {
                throw new AssertFailedExcetpion(string.Format(Messages.Exception_NoExceptionOccuredFormat, typeof(TExcepion).FullName));
            }
        }
        
        private static void AssertExceptionType<TExcepion>(bool allowHandlingAsBaseType, TExcepion ex) where TExcepion : Exception
        {
            if (!allowHandlingAsBaseType && !typeof(TExcepion).Equals(ex.GetType()))
            {
                ExceptionMissmatch<TExcepion>(ex);
            }
        }

        private static void ExceptionMissmatch<TExcepion>(Exception ex) where TExcepion : Exception
        {
            throw new AssertFailedExcetpion(string.Format(Messages.Exception_ExceptionMismatchFormat, typeof(TExcepion).FullName, ex.GetType().FullName));
        }
        
        private static void FurtherAsserts<TExcepion>(Action<TExcepion> assert, TExcepion ex) where TExcepion : Exception
        {
            if (assert != null)
            {
                assert(ex);
            }
        }

        #endregion

        #endregion
    }
}
